package com.wolfking.aggregate;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;

import java.util.Arrays;

/**
 * 并发聚合的动态代理的自动装配
 * 经过隔壁老王处理的JDK动态代理的版本控制的自动注册器
 * spring先调用 ResourceLoaderAware.setResourceLoader
 * 再调用ImportBeanDefinitionRegistrar的registerBeanDefinitions注册SpiScan的bean
 *
 * @author 赵伟伟(wolfking)
 * Created on 2019/7/15 14:48
 */
@Slf4j
class ConcurrentAggregateRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {

    /**
     * 资源加载器
     */
    private ResourceLoader resourceLoader;

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        String[] packages = new String[]{"com"};
        try {
            /*获取启动类的注解 ，在接口上使用@mport，metadata是StandardAnnotationMetadata（本次使用）
             * 如果在实体类上 使用 @Configuration和@Import,metadata是AnnotationMetadataReadingVisitor
             * */
            AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(
                    metadata.getAnnotationAttributes(EnableConcurrentAggregate.class.getName(), true));
            /*获取spi扫描的包路径*/
            if (annotationAttributes != null) {
                packages = annotationAttributes.getStringArray("value");
            }
        } catch (Exception e) {
            log.warn("get the boot EnableConcurrentAggregate error", e);
        }
        Arrays.stream(packages).forEach(str -> log.info("concurrent aggregate will scan package {}", str));
        log.info("scan the concurrent aggregate interface auto proxy");
        ConcurrentAggregateScanner scanner = new ConcurrentAggregateScanner(registry);
        scanner.setResourceLoader(this.resourceLoader);
        try {
            scanner.registerFilters();
            scanner.doScan(packages);
        } catch (Exception ex) {
            log.error("Could not determine auto-configuration package, concurrent aggregate interface scanning disabled.", ex);
        }
    }
}
